use axum::{routing::post, Router};
use serde::Deserialize;

use crate::{
    error::AppErr,
    serialport::{self, address, cmd},
    serve::utils::{Cbor, Void},
};

async fn on_drop_cup(id: Cbor<u8>) -> Result<Void, AppErr> {
    let id = *id;
    serialport::req(
        address::DROP, 
        cmd::drop::DROP_CUP, 
        id
    ).await?.res_result()?;
    Ok(Void)
}

#[derive(Debug, Deserialize)]
struct LedCtrlReq {
    id: u8,
    ctrl: u8,
}

async fn on_led_ctrl(req: Cbor<LedCtrlReq>) -> Result<Void, AppErr> {
    serialport::simple_req(
        address::DROP, 
        cmd::drop::LED, 
        (req.id, req.ctrl)
    ).await?.res_result()?;
    Ok(Void)
}

async fn on_film_reset() -> Result<Void, AppErr> {
    serialport::req(
        address::DROP,
        cmd::drop::FILM_RESET,
        ()
    ).await?.res_result()?;
    Ok(Void)
}

async fn on_robot_reset() -> Result<Void, AppErr> {
    serialport::req(
        address::DROP,
        cmd::drop::ROBOT_RESET,
        ()
    ).await?.res_result()?;
    Ok(Void)
}

async fn on_cut_cup(ctrl: Cbor<u8>) -> Result<Void, AppErr> {
    serialport::req(
        address::DROP,
        cmd::drop::CUT_CUP,
        ctrl.0
    ).await?.res_result()?;
    Ok(Void)
}

pub fn register() -> Router {
    Router::new()
        .route("/drop_cup", post(on_drop_cup))
        .route("/led_ctrl", post(on_led_ctrl))
        .route("/film_reset", post(on_film_reset))
        .route("/robot_reset", post(on_robot_reset))
        .route("/cut_cup", post(on_cut_cup))
}


